﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Collections.Specialized;
using System.Windows.Controls.Primitives;

namespace Gmantis.Controls
{
    public class ListViewerPanel : VirtualizingPanel, INotifyPropertyChanged
    {
        // Fields
        private double _actualZoom = 1.0;
        private ListViewer _control;
        private double? _fillZoom = null;
        private Size? _firstItemDesiredSize = null;
        private ItemContainerGenerator _generator;
        private double? _oneItemZoom = null;
        private AggregatingTable<double, DoubleSumAggregator> _table;
        private ScaleTransform _transform = new ScaleTransform();
        private ListViewerViewport _viewport;
        public static readonly DependencyProperty ZoomProperty = DependencyProperty.Register("Zoom", typeof(ZoomUnit), typeof(ListViewerPanel),
            new PropertyMetadata(ZoomUnit.Fill, delegate(DependencyObject d, DependencyPropertyChangedEventArgs a)
        {
            ListViewerPanel panel = d as ListViewerPanel;
            panel.InvalidateOneItemZoom();
            panel.InvalidateFillZoom();
            panel.UpdateZoom();
        }));

        // Events
        public event PropertyChangedEventHandler PropertyChanged;

        // Methods
        public ListViewerPanel()
        {
            this._viewport = new ListViewerViewport(this);
        }

        protected virtual void AfterItemMeasure(int index, Size desiredSize)
        {
            double num3;
            double num = double.IsInfinity(this.MeasureSize.Width) ? desiredSize.Width : this.MeasureSize.Width;
            double newLength = double.IsInfinity(this.MeasureSize.Height) ? desiredSize.Height : this.MeasureSize.Height;
            if (this.Orientation == Orientation.Vertical)
            {
                this.ScrollingTable.Update(index, newLength);
                num3 = Math.Max(this.NonScrollingLength, num);
            }
            else
            {
                this.ScrollingTable.Update(index, num);
                num3 = Math.Max(this.NonScrollingLength, newLength);
            }
            if (num3 != this.NonScrollingLength)
            {
                this.NonScrollingLength = num3;
                this.InvalidateFillZoom();
            }
        }

        protected virtual void AfterItemPrepared(ListViewerItem listBoxItem)
        {
            listBoxItem.RenderTransform = this._transform;
            listBoxItem.IsPrepared = true;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            double num;
            double num2;
            double num3 = this.ConvertToLayoutCoordinates(this.NonScrollingLength);
            if (this.Orientation == Orientation.Vertical)
            {
                num = this.ConvertToLayoutCoordinates(this.Padding.Top);
                double num4 = finalSize.Width - this.ConvertToLayoutCoordinates((double)(this.Padding.Left + this.Padding.Right));
                num2 = this.ConvertToLayoutCoordinates(this.Padding.Left) + Math.Max((double)0.0, (double)((num4 - num3) / 2.0));
            }
            else
            {
                double num5 = finalSize.Height - this.ConvertToLayoutCoordinates((double)(this.Padding.Top + this.Padding.Bottom));
                num = this.ConvertToLayoutCoordinates(this.Padding.Top) + Math.Max((double)0.0, (double)((num5 - this.ConvertToLayoutCoordinates(this.NonScrollingLength)) / 2.0));
                num2 = this.ConvertToLayoutCoordinates(this.Padding.Left);
            }
            foreach (UIElement element in base.Children)
            {
                double num8;
                double length;
                int index = this.GeneratorForPanel.IndexFromContainer(element);
                double num7 = this.ConvertToLayoutCoordinates(this.ScrollingTable.FindByIndex(index).Offset);
                if (this.Orientation == Orientation.Vertical)
                {
                    num8 = double.IsInfinity(this.MeasureSize.Width) ? element.DesiredSize.Width : this.MeasureSize.Width;
                    length = this.ScrollingTable.GetLength(index);
                    element.Arrange(new Rect(num2 + ((num3 - this.ConvertToLayoutCoordinates(num8)) / 2.0), num + num7, num8, length));
                }
                else
                {
                    num8 = this.ScrollingTable.GetLength(index);
                    length = double.IsInfinity(this.MeasureSize.Height) ? element.DesiredSize.Height : this.MeasureSize.Height;
                    element.Arrange(new Rect(num2 + num7, num + ((num3 - this.ConvertToLayoutCoordinates(length)) / 2.0), num8, length));
                }
            }
            if (!this.Owner.IsZooming)
            {
                foreach (UIElement element2 in base.Children)
                {
                    ListViewerItem item = element2 as ListViewerItem;
                    if ((item.State == ListBoxItemState.Full) && (item.CacheMode != this.Owner.ResizableCache))
                    {
                        item.CacheMode = this.Owner.ResizableCache;
                    }
                    if ((item.State == ListBoxItemState.Preview) && (item.CacheMode != this.Owner.FixedCache))
                    {
                        item.CacheMode = this.Owner.FixedCache;
                    }
                }
            }
            return finalSize;
        }

        private Rect AugmentViewport(Rect viewport, double rate)
        {
            if (this.Orientation == Orientation.Vertical)
            {
                double y = viewport.Top - (viewport.Height * rate);
                double num2 = viewport.Bottom + (viewport.Height * rate);
                return new Rect(new Point(viewport.Left, y), new Point(viewport.Right, num2));
            }
            double x = viewport.Left - (viewport.Width * rate);
            double num4 = viewport.Right + (viewport.Width * rate);
            return new Rect(new Point(x, viewport.Top), new Point(num4, viewport.Bottom));
        }

        protected virtual void BeforeItemRecycled(ListViewerItem listBoxItem)
        {
            listBoxItem.RenderTransform = null;
            listBoxItem.IsPrepared = false;
        }

        protected virtual Size CalculateExtentSize()
        {
            Size size;
            if (this.Orientation == Orientation.Vertical)
            {
                size = new Size(this.NonScrollingLength, this.ScrollingTable.TotalLength());
            }
            else
            {
                size = new Size(this.ScrollingTable.TotalLength(), this.NonScrollingLength);
            }
            return new Size((size.Width + this.Padding.Left) + this.Padding.Right, (size.Height + this.Padding.Top) + this.Padding.Bottom);
        }

        internal void CalculateItemsInViewport(Rect viewport, out int firstIndex, out int lastIndex)
        {
            firstIndex = this.GetIndexAt(new Point(viewport.Left, viewport.Top));
            lastIndex = this.GetIndexAt(new Point(viewport.Right, viewport.Bottom));
        }

        protected internal double ConvertFromLayoutCoordinates(double length)
        {
            return this.ConvertToAbsoluteCoordinates(length);
        }

        protected internal Size ConvertFromLayoutCoordinates(Size size)
        {
            return new Size(this.ConvertFromLayoutCoordinates(size.Width), this.ConvertFromLayoutCoordinates(size.Height));
        }

        protected internal virtual double ConvertToAbsoluteCoordinates(double length)
        {
            return (length / this.ActualZoom);
        }

        protected internal Point ConvertToAbsoluteCoordinates(Point point)
        {
            return new Point(this.ConvertToAbsoluteCoordinates(point.X), this.ConvertToAbsoluteCoordinates(point.Y));
        }

        protected internal Rect ConvertToAbsoluteCoordinates(Rect area)
        {
            return new Rect(this.ConvertToAbsoluteCoordinates(area.X), this.ConvertToAbsoluteCoordinates(area.Y), this.ConvertToAbsoluteCoordinates(area.Width), this.ConvertToAbsoluteCoordinates(area.Height));
        }

        protected internal Size ConvertToAbsoluteCoordinates(Size size)
        {
            return new Size(this.ConvertToAbsoluteCoordinates(size.Width), this.ConvertToAbsoluteCoordinates(size.Height));
        }

        protected internal double ConvertToLayoutCoordinates(double length)
        {
            return this.ConvertToRenderCoordinates(length);
        }

        protected internal Point ConvertToLayoutCoordinates(Point size)
        {
            return new Point(this.ConvertToLayoutCoordinates(size.X), this.ConvertToLayoutCoordinates(size.Y));
        }

        protected internal Size ConvertToLayoutCoordinates(Size size)
        {
            return new Size(this.ConvertToLayoutCoordinates(size.Width), this.ConvertToLayoutCoordinates(size.Height));
        }

        protected internal virtual double ConvertToRenderCoordinates(double length)
        {
            return (length * this.ActualZoom);
        }

        protected internal Point ConvertToRenderCoordinates(Point size)
        {
            return new Point(this.ConvertToRenderCoordinates(size.X), this.ConvertToRenderCoordinates(size.Y));
        }

        protected internal Rect ConvertToRenderCoordinates(Rect rect)
        {
            return new Rect(this.ConvertToRenderCoordinates(rect.X), this.ConvertToRenderCoordinates(rect.Y), this.ConvertToRenderCoordinates(rect.Width), this.ConvertToRenderCoordinates(rect.Height));
        }

        protected internal Size ConvertToRenderCoordinates(Size size)
        {
            return new Size(this.ConvertToRenderCoordinates(size.Width), this.ConvertToRenderCoordinates(size.Height));
        }

        private double? GetFillZoom()
        {
            double nonScrollingLength = 0.0;
            if (this.NonScrollingLength > 0.0)
            {
                nonScrollingLength = this.NonScrollingLength;
            }
            else if (this.Orientation == Orientation.Vertical)
            {
                if (double.IsNaN(this.ItemWidth) || double.IsInfinity(this.ItemWidth))
                {
                    nonScrollingLength = this.EstimatedItemSize.Width;
                }
                else
                {
                    nonScrollingLength = this.ItemWidth;
                }
            }
            else if (double.IsNaN(this.ItemHeight) || double.IsInfinity(this.ItemHeight))
            {
                nonScrollingLength = this.EstimatedItemSize.Height;
            }
            else
            {
                nonScrollingLength = this.ItemHeight;
            }
            if ((nonScrollingLength > 0.0) && (this.ScrollViewer != null))
            {
                if (this.Orientation == Orientation.Vertical)
                {
                    double num2 = this.ScrollViewer.ActualWidth - (this.Padding.Left + this.Padding.Right);
                    if (num2 > 0.0)
                    {
                        return new double?(num2 / nonScrollingLength);
                    }
                }
                else
                {
                    double num3 = this.ScrollViewer.ActualHeight - (this.Padding.Top + this.Padding.Bottom);
                    if (num3 > 0.0)
                    {
                        return new double?(num3 / nonScrollingLength);
                    }
                }
            }
            return null;
        }

        public virtual int GetIndexAt(Point point)
        {
            int count = this.Owner.Items.Count;
            if (count <= 0)
            {
                return -1;
            }
            if (this.Orientation == Orientation.Vertical)
            {
                return Math.Max(0, Math.Min(count - 1, this.ScrollingTable.FindByLength(point.Y - this.Padding.Top).Index));
            }
            return Math.Max(0, Math.Min(count - 1, this.ScrollingTable.FindByLength(point.X - this.Padding.Left).Index));
        }

        public virtual Rect GetItemPosition(int index)
        {
            if ((index < 0) || (index >= this.Owner.Items.Count))
            {
                throw new IndexOutOfRangeException();
            }
            double offset = this.ScrollingTable.FindByIndex(index).Offset;
            double length = this.ScrollingTable.GetLength(index);
            if (this.Orientation == Orientation.Vertical)
            {
                return new Rect(this.ConvertToRenderCoordinates(this.Padding.Left), this.ConvertToRenderCoordinates((double)(this.Padding.Top + offset)), this.ConvertToRenderCoordinates(this.NonScrollingLength), this.ConvertToRenderCoordinates(length));
            }
            return new Rect(this.ConvertToRenderCoordinates((double)(this.Padding.Left + offset)), this.ConvertToRenderCoordinates(this.Padding.Left), this.ConvertToRenderCoordinates(length), this.ConvertToRenderCoordinates(this.NonScrollingLength));
        }

        internal Size GetMaximumItemSize()
        {
            double num = 0.0;
            double num2 = 0.0;
            foreach (UIElement element in base.Children)
            {
                num = Math.Max(num, element.DesiredSize.Width);
                num2 = Math.Max(num2, element.DesiredSize.Height);
            }
            return new Size(num, num2);
        }

        private double? GetOneItemZoom()
        {
            double height = 0.0;
            if (this.Orientation == Orientation.Vertical)
            {
                if (double.IsNaN(this.ItemHeight) || double.IsInfinity(this.ItemHeight))
                {
                    height = this.EstimatedItemSize.Height;
                }
                else
                {
                    height = this.ItemHeight;
                }
            }
            else if (double.IsNaN(this.ItemWidth) || double.IsInfinity(this.ItemWidth))
            {
                height = this.EstimatedItemSize.Width;
            }
            else
            {
                height = this.ItemWidth;
            }
            if ((height > 0.0) && (this.ScrollViewer != null))
            {
                if (this.Orientation == Orientation.Vertical)
                {
                    double actualHeight = this.ScrollViewer.ActualHeight;
                    if (actualHeight > 0.0)
                    {
                        return new double?(actualHeight / height);
                    }
                }
                else
                {
                    double actualWidth = this.ScrollViewer.ActualWidth;
                    if (actualWidth > 0.0)
                    {
                        return new double?(actualWidth / height);
                    }
                }
            }
            return null;
        }

        internal void InvalidateFillZoom()
        {
            this._fillZoom = null;
        }

        internal void InvalidateOneItemZoom()
        {
            this._oneItemZoom = null;
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            if (this.Owner == null)
            {
                return new Size();
            }
            ListViewerPanel panel = this.Owner.Panel;
            if (!this.Owner.IsZooming)
            {
                this.UpdateZoom();
                this._viewport.Dimensions = Rect.Empty;
                if (this.ScrollViewer != null)
                {
                    double actualWidth = this.ScrollViewer.ActualWidth;
                    double actualHeight = this.ScrollViewer.ActualHeight;
                    double horizontalOffset = this.ScrollViewer.HorizontalOffset;
                    double verticalOffset = this.ScrollViewer.VerticalOffset;
                    this._viewport.Dimensions = this.ConvertToAbsoluteCoordinates(new Rect(horizontalOffset, verticalOffset, actualWidth, actualHeight));
                }
                if ((!this._viewport.Dimensions.IsEmpty && (this._viewport.Dimensions.Width > 0.0)) && (this._viewport.Dimensions.Height > 0.0))
                {
                    int num5;
                    int num6;
                    int num7;
                    int num8;
                    bool isScrolling = this.Owner.IsScrolling;
                    bool refreshWhileScrolling = this.Owner.RefreshWhileScrolling;
                    this.ResetScrollingTable();
                    this.CalculateItemsInViewport(this.AugmentViewport(this._viewport.Dimensions, this.ViewportGap), out num5, out num6);
                    this.CalculateItemsInViewport(this.AugmentViewport(this._viewport.Dimensions, this.ViewportPreviewGap), out num7, out num8);
                    this._viewport.FirstVisibleItem = num5;
                    this._viewport.LastVisibleItem = num6;
                    this._viewport.StartPosition = num7;
                    this._viewport.EndPosition = num8;
                    this.RecycleContainers();
                    GeneratorPosition position = base.ItemContainerGenerator.GeneratorPositionFromIndex(num7);
                    using (base.ItemContainerGenerator.StartAt(position, GeneratorDirection.Forward, true))
                    {
                        for (int i = Math.Max(0, num7); i <= Math.Min(this.Owner.Items.Count - 1, num8); i++)
                        {
                            bool flag3;
                            UIElement child = base.ItemContainerGenerator.GenerateNext(out flag3) as UIElement;
                            if (child != null)
                            {
                                ListViewerItem listBoxItem = child as ListViewerItem;
                                if (!listBoxItem.IsPrepared)
                                {
                                    base.AddInternalChild(child);
                                    base.ItemContainerGenerator.PrepareItemContainer(child);
                                    this.AfterItemPrepared(listBoxItem);
                                }
                                bool flag4 = (i >= num5) && (i <= num6);
                                if (!refreshWhileScrolling && isScrolling)
                                {
                                    if (!flag4)
                                    {
                                        listBoxItem.State = ListBoxItemState.Preview;
                                    }
                                }
                                else
                                {
                                    ListBoxItemState state = flag4 ? ListBoxItemState.Full : ListBoxItemState.Preview;
                                    if (state != listBoxItem.State)
                                    {
                                        listBoxItem.State = state;
                                    }
                                }
                                child.Measure(this.MeasureSize);
                                this.AfterItemMeasure(i, child.DesiredSize);
                            }
                        }
                    }
                }
            }
            this.RemoveOrphanChildren();
            return this.ConvertToLayoutCoordinates(this.CalculateExtentSize());
        }

        protected override void OnClearChildren()
        {
            this.Refresh();
        }

        protected override void OnItemsChanged(object sender, System.Windows.Controls.Primitives.ItemsChangedEventArgs args)
        {
            switch (args.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    this._table = null;
                    return;

                case NotifyCollectionChangedAction.Remove:
                    this._table = null;
                    return;

                case NotifyCollectionChangedAction.Replace:
                    if (args.ItemUICount <= 0)
                    {
                        break;
                    }
                    return;

                case (NotifyCollectionChangedAction.Replace | NotifyCollectionChangedAction.Remove):
                    break;

                case NotifyCollectionChangedAction.Reset:
                    this.Refresh();
                    break;

                default:
                    return;
            }
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void RecycleContainers()
        {
            for (int i = base.Children.Count - 1; i >= 0; i--)
            {
                UIElement container = base.Children[i];
                int itemIndex = this.GeneratorForPanel.IndexFromContainer(container);
                if (((itemIndex == -1) || (itemIndex < this._viewport.StartPosition)) || (itemIndex > this._viewport.EndPosition))
                {
                    this.BeforeItemRecycled(container as ListViewerItem);
                    GeneratorPosition position = base.ItemContainerGenerator.GeneratorPositionFromIndex(itemIndex);
                    if (position.Index >= 0)
                    {
                        ((IRecyclingItemContainerGenerator)this.GeneratorForPanel).Recycle(position, 1);
                    }
                    base.RemoveInternalChildRange(i, 1);
                }
            }
        }

        public void Refresh()
        {
            this._table = null;
            this._viewport.FirstVisibleItem = -1;
            this._viewport.LastVisibleItem = -1;
            this._viewport.StartPosition = -1;
            this._viewport.EndPosition = -1;
            this._viewport.Dimensions = Rect.Empty;
            this._firstItemDesiredSize = null;
            this.NonScrollingLength = 0.0;
            this.InvalidateFillZoom();
            this.InvalidateOneItemZoom();
            base.InvalidateMeasure();
            if (base.ItemContainerGenerator != null)
            {
                for (int i = base.Children.Count - 1; i >= 0; i--)
                {
                    ListViewerItem listBoxItem = base.Children[i] as ListViewerItem;
                    this.BeforeItemRecycled(listBoxItem);
                    base.RemoveInternalChildRange(i, 1);
                }
                base.ItemContainerGenerator.RemoveAll();
            }
        }

        private void RemoveOrphanChildren()
        {
            for (int i = base.Children.Count - 1; i >= 0; i--)
            {
                UIElement container = base.Children[i];
                if (this.GeneratorForPanel.IndexFromContainer(container) == -1)
                {
                    base.RemoveInternalChildRange(i, 1);
                }
            }
        }

        private void ResetScrollingTable()
        {
            if (PlatformIndependent.IsInDesignMode(this) && (this.ScrollingTable.Count != this.Owner.Items.Count))
            {
                this._table = null;
                AggregatingTable<double, DoubleSumAggregator> scrollingTable = this.ScrollingTable;
            }
        }

        private void UpdateZoom()
        {
            double oneItemZoom = 1.0;
            if (this.Zoom.IsFixed)
                oneItemZoom = this.Zoom.Value;
            else if (this.Zoom.IsOneItem)
                oneItemZoom = this.OneItemZoom;
            else
                oneItemZoom = this.FillZoom;

            if (this._actualZoom != oneItemZoom)
            {
                this._actualZoom = oneItemZoom;
                this._transform.ScaleX = this._actualZoom;
                this._transform.ScaleY = this._actualZoom;
                this._transform.CenterX = 0.0;
                this._transform.CenterY = 0.0;
                base.InvalidateMeasure();
                this.RaisePropertyChanged("ActualZoom");
            }
        }

        // Properties
        private double ActualMaxZoom
        {
            get
            {
                return this.Owner.ActualMaxZoom;
            }
        }

        private double ActualMinZoom
        {
            get
            {
                return this.Owner.ActualMinZoom;
            }
        }

        public double ActualZoom
        {
            get
            {
                return this._actualZoom;
            }
        }

        internal Size EstimatedItemSize
        {
            get
            {
                if (this._firstItemDesiredSize.HasValue)
                {
                    return this._firstItemDesiredSize.Value;
                }
                if (this.Owner.Items.Count > 0)
                {
                    UIElementCollection children = base.Children;
                    IItemContainerGenerator itemContainerGenerator = base.ItemContainerGenerator;
                    GeneratorPosition position = itemContainerGenerator.GeneratorPositionFromIndex(0);
                    using (itemContainerGenerator.StartAt(position, GeneratorDirection.Forward, true))
                    {
                        bool flag;
                        ListViewerItem item = itemContainerGenerator.GenerateNext(out flag) as ListViewerItem;
                        if (item != null)
                        {
                            item.State = ListBoxItemState.Full;
                            if (!base.Children.Contains(item))
                            {
                                base.AddInternalChild(item);
                            }
                            itemContainerGenerator.PrepareItemContainer(item);
                            this.AfterItemPrepared(item);
                            item.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
                            this._firstItemDesiredSize = new Size?(item.DesiredSize);
                            return this._firstItemDesiredSize.Value;
                        }
                    }
                }
                return new Size();
            }
        }

        internal double FillZoom
        {
            get
            {
                if (!this._fillZoom.HasValue)
                {
                    this._fillZoom = this.GetFillZoom();
                }
                double? nullable = this._fillZoom;
                return Math.Max(this.ActualMinZoom, Math.Min(this.ActualMaxZoom, nullable.HasValue ? nullable.GetValueOrDefault() : 1.0));
            }
        }

        protected ItemContainerGenerator GeneratorForPanel
        {
            get
            {
                if (this._generator == null)
                {
                    UIElementCollection children = base.Children;
                    this._generator = base.ItemContainerGenerator.GetItemContainerGeneratorForPanel(this);
                }
                return this._generator;
            }
        }

        public double ItemHeight
        {
            get
            {
                return this.Owner.ItemHeight;
            }
        }

        public double ItemWidth
        {
            get
            {
                return this.Owner.ItemWidth;
            }
        }

        protected virtual Size MeasureSize
        {
            get
            {
                return new Size(double.IsNaN(this.ItemWidth) ? double.PositiveInfinity : this.ItemWidth, double.IsNaN(this.ItemHeight) ? double.PositiveInfinity : this.ItemHeight);
            }
        }

        internal double NonScrollingLength { get; set; }

        internal double OneItemZoom
        {
            get
            {
                if (!this._oneItemZoom.HasValue)
                {
                    this._oneItemZoom = this.GetOneItemZoom();
                }
                double? nullable = this._oneItemZoom;
                return Math.Max(this.ActualMinZoom, Math.Min(this.ActualMaxZoom, nullable.HasValue ? nullable.GetValueOrDefault() : 1.0));
            }
        }

        public Orientation Orientation
        {
            get
            {
                return this.Owner.Orientation;
            }
        }

        public ListViewer Owner
        {
            get
            {
                if (this._control == null)
                {
                    this._control = ItemsControl.GetItemsOwner(this) as ListViewer;
                }
                return this._control;
            }
        }

        public Thickness Padding
        {
            get
            {
                return this.Owner.Padding;
            }
        }

        internal AggregatingTable<double, DoubleSumAggregator> ScrollingTable
        {
            get
            {
                if (this._table == null)
                {
                    double num;
                    if (this.Orientation == Orientation.Vertical)
                    {
                        num = double.IsInfinity(this.MeasureSize.Height) ? this.EstimatedItemSize.Height : this.MeasureSize.Height;
                    }
                    else
                    {
                        num = double.IsInfinity(this.MeasureSize.Width) ? this.EstimatedItemSize.Width : this.MeasureSize.Width;
                    }
                    double[] lengths = new double[this.Owner.Items.Count];
                    for (int i = 0; i < lengths.Length; i++)
                    {
                        lengths[i] = num;
                    }
                    this._table = new AggregatingTable<double, DoubleSumAggregator>(lengths);
                }
                return this._table;
            }
        }

        protected System.Windows.Controls.ScrollViewer ScrollViewer
        {
            get
            {
                if (this.Owner != null)
                {
                    return this.Owner.ScrollViewer;
                }
                return null;
            }
        }

        internal ListViewerViewport Viewport
        {
            get
            {
                return this._viewport;
            }
        }

        public double ViewportGap
        {
            get
            {
                return this.Owner.ViewportGap;
            }
        }

        public double ViewportPreviewGap
        {
            get
            {
                return this.Owner.ViewportPreviewGap;
            }
        }

        public ZoomUnit Zoom
        {
            get
            {
                return (ZoomUnit)base.GetValue(ZoomProperty);
            }
            set
            {
                base.SetValue(ZoomProperty, value);
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, Size = 1)]
    internal struct DoubleSumAggregator : IAggregator<double>
    {
        double IAggregator<double>.Zero()
        {
            return 0.0;
        }

        double IAggregator<double>.Sum(double left, double right)
        {
            return (left + right);
        }

        int IAggregator<double>.Compare(double x, double y)
        {
            return x.CompareTo(y);
        }
    }
}
